package online.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * URI保存フィルタ
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class RecordURIFilter implements Filter {
	/** コンテキストPATH */
	public static final String CONTEXT_PATH = "CONTEXT";
	/** リクエストPATH */
	public static final String REQUEST_PATH = "REQUEST_PATH";
	/** リクエストURI */
	public static final String REQUEST_URI = "REQUEST_URI";
	/** クエリ文字列 */
	public static final String REQUEST_QUERY = "REQUEST_QUERY";
	/** レスポンスPATH */
	public static final String RESPONSE_PATH = "RESPONSE_PATH";
	/** レスポンスURI */
	public static final String RESPONSE_URI = "RESPONSE_URI";
	/** クエリ文字列 */
	public static final String RESPONSE_QUERY = "RESPONSE_QUERY";

	/** キー */
	private static final String CLAZZ = RecordURIFilter.class.getName();

	/**
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(final FilterConfig filterConfig) throws ServletException {
		return;
	}

	/**
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
		return;
	}

	/**
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(final ServletRequest svRequest, final ServletResponse svResponse,
			final FilterChain chain) throws IOException, ServletException {
		if (HttpServletRequest.class.isInstance(svRequest)) {
			HttpServletRequest request = HttpServletRequest.class.cast(svRequest);

			if (request.getAttribute(CLAZZ) == null) {
				request.setAttribute(CLAZZ, CLAZZ);

				request(request);
				request.setAttribute(CONTEXT_PATH, request.getContextPath());

				response(request);
			} else if (!FilterUtil.isView(request)) {
				response(request);
			}
		}

		chain.doFilter(svRequest, svResponse);
	}

	/**
	 * 初期化
	 * @param request リクエスト
	 */
	private void request(final HttpServletRequest request) {
		request.setAttribute(REQUEST_PATH, request.getRequestURI().substring(
				request.getContextPath().length() + "/".length()));
		request.setAttribute(REQUEST_URI, request.getRequestURI());
		request.setAttribute(REQUEST_QUERY, request.getQueryString());
	}

	/**
	 * 記録
	 * @param request リクエスト
	 */
	private void response(final HttpServletRequest request) {
		request.setAttribute(RESPONSE_PATH, request.getRequestURI().substring(
				request.getContextPath().length() + "/".length()));
		request.setAttribute(RESPONSE_URI, request.getRequestURI());
		request.setAttribute(RESPONSE_QUERY, request.getQueryString());
	}

	/**
	 * コンテキストPATH取得
	 * @param request リクエスト
	 * @return コンテキストPATH
	 */
	public static String getContextPath(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(CONTEXT_PATH));
	}

	/**
	 * リクエストPATH取得
	 * @param request リクエスト
	 * @return リクエストPATH
	 */
	public static String getRequestPath(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(REQUEST_PATH));
	}

	/**
	 * レスポンスPATH取得
	 * @param request レスポンス
	 * @return レスポンスPATH
	 */
	public static String getResponsePath(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(RESPONSE_PATH));
	}

	/**
	 * リクエストURI取得
	 * @param request リクエスト
	 * @return リクエストURI
	 */
	public static String getRequestUri(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(REQUEST_URI));
	}

	/**
	 * レスポンスURI取得
	 * @param request レスポンス
	 * @return レスポンスURI
	 */
	public static String getResponseUri(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(RESPONSE_URI));
	}

	/**
	 * リクエストクエリ文字列取得
	 * @param request リクエスト
	 * @return リクエストクエリ文字列
	 */
	public static String getRequestQuery(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(REQUEST_QUERY));
	}

	/**
	 * レスポンスクエリ文字列取得
	 * @param request リクエスト
	 * @return レスポンスクエリ文字列
	 */
	public static String getResponseQuery(final HttpServletRequest request) {
		return String.class.cast(request.getAttribute(RESPONSE_QUERY));
	}
}
